home *** CD-ROM | disk | FTP | other *** search
Text File | 1997-04-25 | 8.3 KB | 277 lines | [TEXT/CWIE] |
- // ==================================================
- // UDragDropSuit.cp
- // Copyright (C) 1996-1997 Mizutori Tetsuya
- // November 22, 1996; February 6, 1997.
- // ==================================================
- // All documents are pretty-printed in 10-point Geneva font.
-
-
- #include <LDragAndDrop.h>
-
- #include "UDragDropSuit.h"
-
-
- // === Static Class Variables ===
- RgnHandle UDragDropSuit::sDragRegion = ::NewRgn();
-
-
- // --------------------------------------------------
- // • DragText
- // --------------------------------------------------
- // Drag the selected text in the given document.
- // Author: Rob Johnston @ Apple Computer, Inc.
- // Date: Friday, September 10, 1993
- // Modifier: Mizutori Tetsuya, November 22, 1996
-
- Boolean
- UDragDropSuit::DragText(
- const EventRecord & theEvent,
- RgnHandle inHiliteRgn,
- unsigned char * textP,
- long & textLen,
- Boolean & wasDroppedInTrash )
- {
- if ( ! LDropArea::DragAndDropIsPresent() ) return false;
-
- Boolean result = true;
-
- wasDroppedInTrash = false;
-
- // Wait for the mouse to move to the mouse button to be released. If the mouse button was
- // released before the mouse moves, return false. Returing false from DragText means that
- // a drag operation did not occur.
-
- if ( ! ::WaitMouseMoved(theEvent.where) ) return false;
-
- // Prepare a drag handler.
- DragReference theDrag;
- ::NewDrag( &theDrag );
-
- // For purposes of demonstration, we insert the 'TEXT' data and promise 'styl'
- // data. If a receiver requests 'TEXT', the Drag Manager will give them the text
- // without needing us to intervene. If a receiver requests 'styl', the Drag Manager
- // will call our MySendDataProc to provide the data at drop time. The MySendDataProc
- // is specified by calling SetDragSendProc.
- ::AddDragItemFlavor( theDrag, 1, 'TEXT', textP, textLen, 0L );
-
- //::SetDragSendProc( theDrag, (DragSendDataUPP) sDragSendDataProc, (void *) this );
-
- //::SetDragDrawingProc( theDrag, (DragDrawingUPP) sDragDrawingProc, (void *) this );
-
- if ( ! MyTrackDrag( theDrag, theEvent, inHiliteRgn ) ) goto bail;
-
- // Check to see if the drop occurred in the Finder's Trash. If the drop occurred
- // in the Finder's Trash and a copy operation wasn't specified, delete the
- // source selection. Note that we can continute to get the attributes, drop location
- // modifiers, etc. of the drag until we dispose of it using DisposeDrag.
- DragAttributes attributes;
- ::GetDragAttributes( theDrag, &attributes );
-
- #ifdef COMMENT
- if ( (attributes & dragInsideSenderWindow) == 0 ) {
- result = false;
- } else
- #endif // COMMENT
-
- if ( (attributes & dragInsideSenderApplication) == 0 ) {
-
- AEDesc dropLocation;
- ::GetDropLocation( theDrag, &dropLocation );
-
- short mouseDownModifiers, mouseUpModifiers;
- ::GetDragModifiers( theDrag, 0L, &mouseDownModifiers, &mouseUpModifiers );
-
- short copyText = (mouseDownModifiers | mouseUpModifiers) & optionKey;
- if ( copyText == 0 && DropLocationIsFinderTrash( dropLocation ) ) {
- wasDroppedInTrash = true;
- }
-
- ::AEDisposeDesc( &dropLocation );
- }
-
- bail:
- // Dispose of the drag.
- if ( theDrag != NULL ) ::DisposeDrag( theDrag );
-
- return result;
- }
-
-
- // --------------------------------------------------
- // • MyTrackDrag
- // --------------------------------------------------
- // Do my TrackDrag, respecting to which the mouse position is in the original drag region.
-
- Boolean
- UDragDropSuit::MyTrackDrag(
- DragReference inDrag,
- const EventRecord & inMacEvent,
- RgnHandle inDragRegion )
- {
- // Copy the hilite region into dragRegion and offset it into global coordinates.
- // CAUTION: you must ::SetPort() before getting ::LocalToGlobal().
- RgnHandle dragRegion = ::NewRgn();
- ::CopyRgn( inDragRegion, dragRegion );
-
- Point theLocalOrigin;
- ::SetPt( &theLocalOrigin, 0, 0 );
- ::LocalToGlobal( &theLocalOrigin );
- ::OffsetRgn( dragRegion, theLocalOrigin.h, theLocalOrigin.v );
-
- // Set my original drag region.
- ::CopyRgn( dragRegion, sDragRegion );
-
- // Set the item's bounding rectangle in global coordinates.
- ::SetDragItemBounds( inDrag, 1, &(**dragRegion).rgnBBox );
-
- // Prepare the drag region.
- RgnHandle tempRgn = ::NewRgn();
- ::CopyRgn( dragRegion, tempRgn );
- ::InsetRgn( tempRgn, 1, 1 );
- ::DiffRgn( dragRegion, tempRgn, dragRegion );
- ::DisposeRgn( tempRgn );
-
- // Drag the text. TrackDrag will return userCanceledErr if the drop zoomed-back
- // for any reason.
- OSErr err;
- err = ::TrackDrag( inDrag, &inMacEvent, dragRegion );
-
- ::DisposeRgn( dragRegion );
-
- ::SetEmptyRgn( sDragRegion );
-
- return ( err == noErr || err == userCanceledErr );
- }
-
-
- // --------------------------------------------------
- // • DropLocationIsFinderTrash
- // --------------------------------------------------
- // Returns true if the given dropLocation AEDesc is a descriptor of the Finder's Trash.
- // Author: Rob Johnston @ Apple Computer, Inc.
- // Date: Friday, September 10, 1993
- // Modifier: Mizutori Tetsuya, November 22, 1996
-
- Boolean
- UDragDropSuit::DropLocationIsFinderTrash(
- AEDesc & dropLocation )
-
- {
- // Coerce the dropLocation descriptor to an FSSpec. If there's no dropLocation or
- // it can't be coerced into an FSSpec, then it couldn't have been the Trash.
- if ( dropLocation.descriptorType == typeNull ) return false;
-
- AEDesc dropSpec;
- if ( ::AECoerceDesc( &dropLocation, typeFSS, &dropSpec ) != noErr ) return false;
-
- ::HLock( dropSpec.dataHandle );
- FSSpec * theSpec = (FSSpec *) *dropSpec.dataHandle;
-
- // Get the directory ID of the given dropLocation object.
-
- CInfoPBRec thePB;
- thePB.dirInfo.ioCompletion = 0L;
- thePB.dirInfo.ioNamePtr = (StringPtr) &theSpec->name;
- thePB.dirInfo.ioVRefNum = theSpec->vRefNum;
- thePB.dirInfo.ioFDirIndex = 0;
- thePB.dirInfo.ioDrDirID = theSpec->parID;
-
- OSErr err = ::PBGetCatInfoSync( &thePB );
-
- ::HUnlock( dropSpec.dataHandle );
- ::AEDisposeDesc( &dropSpec );
-
- if ( err != noErr ) return false;
-
- // If the result is not a directory, it must not be the Trash.
- if ((thePB.dirInfo.ioFlAttrib & (1 << 4)) == 0 ) return false;
-
- // Get information about the Trash folder.
- short trashVRefNum;
- long trashDirID;
- ::FindFolder( theSpec->vRefNum, kTrashFolderType, kCreateFolder, &trashVRefNum, &trashDirID );
-
- // If the directory ID of the dropLocation object is the same as the directory ID
- // returned by FindFolder, then the drop must have occurred into the Trash.
- if ( thePB.dirInfo.ioDrDirID == trashDirID ) return true;
-
- return false;
- }
-
-
- // --------------------------------------------------
- // • InDragRegion
- // --------------------------------------------------
- // Determine which the current mouse position is in the initial drag region.
-
- Boolean
- UDragDropSuit::InDragRegion(
- DragReference inDragRef )
- {
- OSErr err;
- Boolean result = false;
-
- Point theMouseOrg;
- Point theMousePos;
- err = ::GetDragMouse( inDragRef, &theMousePos, NULL );
- err = ::GetDragOrigin( inDragRef, &theMouseOrg );
-
- result = ::PtInRgn( theMousePos, sDragRegion );
-
- return result;
- }
-
-
- // --------------------------------------------------
- // • ZoomBackBounds
- // --------------------------------------------------
- // Provide zooming rects from destination to source when the drag was failed.
-
- void
- UDragDropSuit::ZoomBackBounds(
- DragReference inDragRef,
- ItemReference inItemRef )
- {
- OSErr err;
-
- Point theMouseOrg;
- Point theMousePos;
- Point thePinnedMousePos;
- err = ::GetDragMouse( inDragRef, &theMousePos, &thePinnedMousePos );
- err = ::GetDragOrigin( inDragRef, &theMouseOrg );
-
- Point theDelta = theMouseOrg;
- ::SubPt( theMousePos, &theDelta );
-
- if ( ::EmptyRgn( sDragRegion ) ) {
-
- // Retrieve the icon bounds which was set by the Finder.
- // But we can not get the CORRECT bounds for it, the reason why I do not know.
- Rect theBoundRect;
- ::GetDragItemBounds( inDragRef, inItemRef, &theBoundRect );
- // ::OffsetRect( &theBoundRect, thePinnedMousePos.h, thePinnedMousePos.v );
- ::OffsetRect( &theBoundRect, - theBoundRect.left, - theBoundRect.top );
-
- Rect fromRect = theBoundRect;
- Rect toRect = theBoundRect;
- // ::OffsetRect( &toRect, theDelta.h, theDelta.v );
- ::OffsetRect( &fromRect, theMousePos.h, theMousePos.v );
- ::OffsetRect( &toRect, theMouseOrg.h, theMouseOrg.v );
-
- ::ZoomRects( &fromRect, &toRect, 12, zoomDecelerate );
-
- } else {
-
- RgnHandle theDropRgn = ::NewRgn();
- ::CopyRgn( sDragRegion, theDropRgn );
- ::OffsetRgn( theDropRgn, - theDelta.h, - theDelta.v );
-
- ::ZoomRegion( theDropRgn, theDelta, 12, zoomDecelerate );
-
- ::DisposeRgn( theDropRgn );
- }
- }
-
-
- // end of program
-